package com.zhang.crowd.util;

import com.aliyun.api.gateway.demo.util.HttpUtils;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.common.comm.ResponseMessage;
import com.aliyun.oss.model.PutObjectResult;
import com.zhang.crowd.constant.CrowdConstant;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;


import javax.servlet.http.HttpServletRequest;
import java.io.FileInputStream;
import java.io.InputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 通用方法工具类
 */
public class CrowdUtil {



    /**
     * 专门负责上传文件到 OSS 服务器的工具方法
     * @param endpoint OSS 参数
     * @param accessKeyId OSS 参数
     * @param accessKeySecret OSS 参数
     * @param inputStream 要上传的文件的输入流
     * @param bucketName OSS 参数
     * @param bucketDomain OSS 参数
     * @param originalName 要上传的文件的原始文件名
     * @return 包含上传结果以及上传的文件在 OSS 上的访问路径
     */
    public static ResultEntity<String> uploadFileToOss(
            String endpoint,
            String accessKeyId,
            String accessKeySecret,
            InputStream inputStream,
            String bucketName,
            String bucketDomain,
            String originalName) {
        // 创建 OSSClient 实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
        // 生成上传文件的目录
        String folderName = new SimpleDateFormat("yyyyMMdd").format(new Date());
        // 生成上传文件在 OSS 服务器上保存时的文件名
        // 原始文件名：beautfulgirl.jpg
        // 生成文件名：wer234234efwer235346457dfswet346235.jpg
        // 使用 UUID 生成文件主体名称
        String fileMainName = UUID.randomUUID().toString().replace("-", "");
        // 从原始文件名中获取文件扩展名
        String extensionName = originalName.substring(originalName.lastIndexOf("."));
        // 使用目录、文件主体名称、文件扩展名称拼接得到对象名称
        String objectName = folderName + "/" + fileMainName + extensionName;
        try {
        // 调用 OSS 客户端对象的方法上传文件并获取响应结果数据
            PutObjectResult putObjectResult = ossClient.putObject(bucketName, objectName,
                    inputStream);
        // 从响应结果中获取具体响应消息
            ResponseMessage responseMessage = putObjectResult.getResponse();
        // 根据响应状态码判断请求是否成功
            if(responseMessage == null) {
        // 拼接访问刚刚上传的文件的路径
                String ossFileAccessPath = bucketDomain + "/" + objectName;
        // 当前方法返回成功
                return ResultEntity.successWithData(ossFileAccessPath);
            } else {
        // 获取响应状态码
                int statusCode = responseMessage.getStatusCode();

                // 如果请求没有成功，获取错误消息
                String errorMessage = responseMessage.getErrorResponseAsString();
        // 当前方法返回失败
                return ResultEntity.failed(" 当 前 响 应 状 态 码 ="+statusCode+" 错 误 消 息 ="+errorMessage);
            }
        } catch (Exception e) {
            e.printStackTrace();
        // 当前方法返回失败
            return ResultEntity.failed(e.getMessage());
        } finally {
            if(ossClient != null) {
        // 关闭 OSSClient。
                ossClient.shutdown();
            }
        }
    }


/*    public static void main(String[] args)  {
        try{
            FileInputStream inputStream =new FileInputStream("D:\\桌面\\maven\\crowdfunding01-admin-parent\\crowdfunding05-common-util\\src\\main\\java\\com\\zhang\\crowd\\util\\4.jpg");
            ResultEntity resultEntity = uploadFileToOss(
                    "http://oss-cn-nanjing.aliyuncs.com",
                    "LTAI5tB5wRCc5NhtGZmHCeoY",
                    "EfO7ufoF1o4JmFDiNsYCMcndNgJO22",
                    inputStream,
                    "zhangjunjie0318",
                    "http://zhangjunjie0318.oss-cn-nanjing.aliyuncs.com",
                    "4.jpg");
            System.out.println(resultEntity);
            System.out.println("zhang");
        }catch (Exception e){
            e.printStackTrace();
        }


    }*/



    /**
     * 给远程的三方接口发送请求，把生成的验证码发送到用户的手机号上
     * @param host          短信接口调用的URL地址
     * @param path          具体发送短信功能的地址
     * @param method        请求方式
     * @param phoneNum      用户的手机号
     * @param appCode       三方短信API的APPCode
     * @param sign          签名编号
     * @param template_id   模板编号
     * @return
     *      成功：返回验证码
     *      失败：返回错误消息
     */
    public static ResultEntity<String> sendShortMessage(
            String host,

            String path,

            String method,

            String phoneNum,

            String appCode,

            String sign,

            String template_id){
        //String host = "https://dfsns.market.alicloudapi.com";
        //String path = "/data/send_sms";
        //String method = "POST";
        //String appcode = "0eb850567e4742ed9f2eb268b6f5df42";

        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appCode);
        //根据API的要求，定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        //生成验证码
        StringBuilder code = new StringBuilder();
        for(int i = 0; i < 4; i++ ){
            int result = (int)(Math.random()*10);
            code.append(result);
        }


        // 要发送的验证码
        bodys.put("content", "code:"+code+",expire_at:3");
        // 收短信的手机号
        bodys.put("phone_number", phoneNum);
        // 签名编号
        bodys.put("template_id",template_id);
        //这里默认模板有两个：
        //"TPL_0000"
        //"TPL_0001"

        try {
            /**
             * 重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            StatusLine statusLine = response.getStatusLine();

            int statusCode = statusLine.getStatusCode();

            //logger.info("statusCode===================>"+statusCode);
            String reasonPhrase = statusLine.getReasonPhrase();

            if(statusCode == 200){
                return ResultEntity.successWithData(code.toString());
            }
                return ResultEntity.failed(reasonPhrase);


            //logger.info("reasonPhrase===================>"+reasonPhrase);
            //获取response的body
            //logger.info("======================>"+ EntityUtils.toString(response.getEntity()));


        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }




    /**
     * 判断当前请求是否是Ajax请求
     * @param request   请求对象
     * @return
     *      true: 当前请求是Ajax请求
     *      false:当前请求不是Ajax请求
     */
    public static boolean judgeRequestType(HttpServletRequest request){
        // 1、获取请求消息头
        String acceptHeader = request.getHeader("Accept");
        String xRequestHeader = request.getHeader("XMLHttpRequest");

        // 2、判断
        return  (acceptHeader != null && acceptHeader.contains("application/json"))
            ||
                ((xRequestHeader != null) && xRequestHeader.contains("XMLHttpRequest"));
    }




    /**
     * 对明文字符串进行MDB加密
     * @param source 传入的明文字符串
     * @return  加密结果
     */
    public static String md5(String source){
        // 1.判断source是否有效
        if(source == null || source.length()==0){

            // 2.如果不是有效字符串就抛出异常
            throw new RuntimeException(CrowdConstant.MESSAGE_STRING_INVALIDATE);
        }


        try{
            // 3.获取MessageDigest对象
            String algorithm = "md5";

            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);

            // 4.获取明文字符串对应的字节数组
            byte[] input = source.getBytes();

            // 5.执行加密
            byte[] output = messageDigest.digest(input);

            // 6.创建BigInteger对象
            int signum = 1;
            BigInteger bigInteger = new BigInteger(signum,output);

            // 7.按照16进制将bigInterger的值转换为字符串
            int radix = 16;
            String encoded = bigInteger.toString(radix).toUpperCase();

            return encoded;
        }catch (NoSuchAlgorithmException e){
            e.printStackTrace();
        }
       return null;
    }




}
